#include "NetworkSanner.h"
#include "ARPScanner.h"
#include "ICMPScanner.h"
#include "Common.h"
#include "InitSock.h"
#include "TCPScanner.h"
#include "UDPScanner.h"

CInitSock InitSock;

NetworkSanner::NetworkSanner(QObject *parent)
    : QObject{parent}
{
    m_arpScanner = new ARPScanner;
    m_arpScanner->OnSucceeded.AddLambda([this](char* DestIP, char* MacAddr){
        if(MacAddr && DestIP)
        {
            printf("%s\n", DestIP);
            printf("%s\n", MacAddr);
            emit SendARPItem(DestIP, MacAddr);
        }
    });

    m_icmpScanner = new ICMPScanner;
    m_icmpScanner->OnResult.AddLambda([this](char* DestIP, bool bIsAlive){
        emit SendICMPInfo(DestIP, bIsAlive);
    });

    m_tcpScanner = new TCPScanner;
    m_tcpScanner->OnResult.AddLambda([this](QVector<QString> item){
        emit SendTCPConnectItem(item);
    });
    m_tcpScanner->OnEnd.AddLambda([this](){
        emit TCPConnectEnd();
    });
    m_tcpScanner->OnSynResult.AddLambda([this](QVector<QString> item){
        emit SendTCPSynItem(item);
    });
    m_tcpScanner->OnFinResult.AddLambda([this](QVector<QString> item){
        emit SendTCPFinItem(item);
    });

    m_udpScanner = new UDPScanner;
    m_udpScanner->OnResult.AddLambda([this](QVector<QString> item){
        emit SendUDPItem(item);
    });

}

NetworkSanner::~NetworkSanner()
{
    if(m_arpScanner)
    {
        delete m_arpScanner;
        m_arpScanner = nullptr;
    }
}

void NetworkSanner::Arp_Scan(QString startIPStr, QString endIPStr)
{
    int startIp = ip2num(startIPStr);
    int endIp = ip2num(endIPStr);
    for(;startIp <= endIp; ++startIp)
    {
        m_arpScanner->SendARP(num2ip(startIp).toStdString().c_str());
    }
}

void NetworkSanner::ICMP_Scan(QString dstIPStr)
{
    if(m_icmpScanner)
    {
        m_icmpScanner->SendRequest(dstIPStr.toStdString().c_str());
    }
}

void NetworkSanner::TCP_Connect_Scan(QString startIPStr, QString endIPStr, ushort startPort, ushort endPort)
{
    if(m_tcpScanner)
    {
        m_tcpScanner->TCP_Connect_Scan(startIPStr.toStdString().c_str(), endIPStr.toStdString().c_str(), startPort, endPort);
    }
}

void NetworkSanner::TCP_Syn_Scan(QString DestIP, unsigned short StartPort, unsigned short EndPort)
{
    if(m_tcpScanner)
    {
        m_tcpScanner->TCP_Syn_Scan(DestIP.toStdString().c_str(), StartPort, EndPort);
    }
}

bool NetworkSanner::CheckIP(QString IP)
{
    return checkip(IP);
}

void NetworkSanner::StopTCPSyn()
{
    if(m_tcpScanner)
    {
        m_tcpScanner->SetSynStopping(true);
    }
}

void NetworkSanner::StartTCPSyn()
{
    if(m_tcpScanner)
    {
        m_tcpScanner->SetSynStopping(false);
    }
}

void NetworkSanner::TCP_Fin_Scan(QString DestIP, unsigned short StartPort, unsigned short EndPort)
{
    if(m_tcpScanner)
    {
        m_tcpScanner->TCP_Fin_Scan(DestIP.toStdString().c_str(), StartPort, EndPort);
    }
}

void NetworkSanner::StopTCPFin()
{
    if(m_tcpScanner)
    {
        m_tcpScanner->SetFinStopping(true);
    }
}

void NetworkSanner::StartTCPFin()
{
    if(m_tcpScanner)
    {
        m_tcpScanner->SetFinStopping(false);
    }
}

void NetworkSanner::UDP_Scan(QString DestIP, unsigned short StartPort, unsigned short EndPort)
{
    if(m_udpScanner)
    {
        m_udpScanner->UDP_Scan(DestIP.toStdString().c_str(), StartPort, EndPort);
    }
}
